package com.huanghj.base.hessianAnnotations.builder;



import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.remoting.caucho.HessianServiceExporter;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.context.WebApplicationContext;

import com.huanghj.base.hessianAnnotations.HessianServer;
import com.huanghj.base.hessianAnnotations.HttpHessianServlet;


/**
 * 自动加载Hessian所需要的bean  
 * cenxi  2016-12-17
 * */
public class HessianServerBuilder implements InitializingBean,ApplicationContextAware {

	private ApplicationContext applicationContext;
	
	public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
		this.applicationContext = applicationContext;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void afterPropertiesSet() throws Exception {
		System.out.println("HessianServerBuilder start ...");
		// 获取bean工厂并转换为DefaultListableBeanFactory
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
		// 手动注册servlet
		ServletContext sc = ((WebApplicationContext) applicationContext).getServletContext();
		HttpHessianServlet httpHessianServlet = sc.createServlet(HttpHessianServlet.class);
		Map<String, HttpRequestHandler> requestHandlerMap = new HashMap<String, HttpRequestHandler>();
		httpHessianServlet.setRequestHandlerMap(requestHandlerMap);
		ServletRegistration sr = sc.addServlet( "annotationHessianHttpServlet", httpHessianServlet);
		
		//不能为空
		if(sr == null ){
			return;
		}
		
		try {
			sr.addMapping("/annotationHessian/*");
			Object obj = null;
			Class clazz = null;
			String[] beanNames = applicationContext.getBeanDefinitionNames();
			for (String beanName : beanNames) {
				obj = applicationContext.getBean(beanName);
				if(AopUtils.isAopProxy(obj)){
					Object realObj = AopTargetUtils.getTarget(obj);
					obj = realObj;
				}
				
				clazz = obj.getClass();
				// 判断是否是Remote
				Annotation remote = clazz.getAnnotation(HessianServer.class);
				if (remote != null) {
					// 获取类实现的接口
					String interfaceStr = "";
					// 获取接口名称
					String interfaceSimpleName = "";

					Class<?> inter[] = null;// 声明一个对象数组
					inter = clazz.getInterfaces();// 获取类实现的所有接口
					if (inter != null && inter.length > 0) {
						interfaceStr = inter[0].getName();
						interfaceSimpleName = inter[0].getSimpleName();

						// 首字母小写
						String first = interfaceSimpleName.substring(0, 1).toLowerCase();
						String rest = interfaceSimpleName.substring(1,interfaceSimpleName.length());
						interfaceSimpleName = new StringBuffer(first).append(rest).toString();
					}
					// 通过BeanDefinitionBuilder创建bean定义
					BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(HessianServiceExporter.class);
					AbstractBeanDefinition beanProxyDefinition = beanDefinitionBuilder.getBeanDefinition();
					// 设置属性
					MutablePropertyValues propertyValues = new MutablePropertyValues();
					propertyValues.addPropertyValue("service", applicationContext.getBean(beanName));
					propertyValues.addPropertyValue("serviceInterface", interfaceStr);
					beanProxyDefinition.setPropertyValues(propertyValues);
					// 注册bean 这一步是很关键的，如果beanFactory不是注册bean的 class 而是注册
					// bean的定义definition
					beanFactory.registerBeanDefinition("/" + interfaceSimpleName, beanProxyDefinition);

					System.out.println("create hessian server bean:" + "/" + interfaceSimpleName);

					try {
						// 这里就实例化生成了bean,如果不调用这个方法，那么如果bean在其他地方使用了，同样也是会被实例化的
						Object o = beanFactory.getBean("/" + interfaceSimpleName);
						if(AopUtils.isAopProxy(o)){
							Object real = AopTargetUtils.getTarget(o);
							o = real;
						}
						
						HessianServiceExporter hessianServiceExporter = (HessianServiceExporter)o;//beanFactory.getBean("/" + interfaceSimpleName, HessianServiceExporter.class);
						requestHandlerMap.put("/" + interfaceSimpleName, hessianServiceExporter);
					} catch (Exception e) {
						System.out.println("create hessian server bean:" + "/" + interfaceSimpleName + " 时发生异常！");
						e.printStackTrace();
					}
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
